package com.gzh;

import java.beans.*;
import java.util.stream.Stream;

/**
 * @author gzh
 * @date 2022/5/6 16:02
 * @description
 * • IoC容器主要实现
 * • Java SE
 *      • Java Beans
 *      • Java ServiceLoader SPI
 *      • JNDI（Java Naming and Directory Interface）
 * • Java EE
 *      • EJB（Enterprise Java Beans）
 *      • Servlet
 * • 开源
 *      • Apache Avalon（http://avalon.apache.org/closed.html）
 *      • PicoContainer（http://picocontainer.com/）
 *      • Google Guice（https://github.com/google/guice）
 *      • Spring Framework（https://spring.io/projects/spring-framework）
 *
 * 依赖查找和依赖注入
 * 类型      依赖处理    实现便利性   代码侵入性     API依赖性     可读性
 * 依赖查找   主动获取    相对繁琐    侵入业务逻辑   依赖容器API    良好
 * 依赖注入   被动提供    相对便利    低侵入性      不依赖容器API   一般
 *
 *
 * 依赖查找和依赖注入的区别？
 * 答：依赖查找是主动或手动的依赖查找方式，通常需要依赖容器或标准 API
 * 实现。而依赖注入则是手动或自动依赖绑定的方式，无需依赖特定的容器和
 * API
 *
 *  Spring 作为 IoC 容器有什么优势？
 *  答：
 * 典型的 IoC 管理，依赖查找和依赖注入
 * AOP 抽象
 * 事务抽象
 * 事件机制
 * SPI 扩展
 * 强大的第三方整合
 * 易测试性
 * 更好的面向对象
 */
public class BeanInfoDemo {

    public static void main(String[] args) throws IntrospectionException {
        //通过Java Beans自省的方式进行操作
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);

        Stream.of(beanInfo.getPropertyDescriptors())
                .forEach(propertyDescriptor -> {
                    //PropertyDescriptors 允许添加属性编辑器 - PropertyEditor
                    //GUI -> text(String) -> propertyType
                    //name -> String
                    //age -> Integer
                    Class<?> propertyType = propertyDescriptor.getPropertyType();
                    String propertyName = propertyDescriptor.getName();
                    if ("age".equals(propertyName)) {
                        // String -> Integer
                        // Integer.valueOf("");
                        propertyDescriptor.setPropertyEditorClass(StringToIntegerPropertyEditor.class);
                    }
                    System.out.println(propertyDescriptor);
                });


    }

    static class StringToIntegerPropertyEditor extends PropertyEditorSupport {

        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            Integer value = Integer.valueOf(text);
            setValue(value);
        }
    }
}
